package com.ruoyi.base.interceptor;

import com.ruoyi.base.annotaion.PermissionCheck;
import com.ruoyi.base.annotaion.TokenIgnore;
import com.ruoyi.base.enums.ExceptionEnum;
import com.ruoyi.base.exception.SysException;
import com.ruoyi.base.permission.PermissionManager;
import com.ruoyi.base.permission.TokenManager;
import com.ruoyi.base.utils.spring.SpringUtils;
import com.ruoyi.platform.system.user.enums.UserAccountStatusEnum;
import com.ruoyi.platform.system.user.pojo.LoginUserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * token拦截器 验证token有效性
 *
 * @author ruoyi
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private PermissionManager permissionManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            //判断是否忽略token
            HandlerMethod handlerMethod = (HandlerMethod) handler;

            Method method = handlerMethod.getMethod();
            Class<?> beanType = handlerMethod.getBeanType();

            TokenIgnore tokenIgnoreOnMethod = method.getAnnotation(TokenIgnore.class);
            TokenIgnore tokenIgnoreOnType = beanType.getAnnotation(TokenIgnore.class);
            if (tokenIgnoreOnMethod != null || tokenIgnoreOnType != null) {
                return true;
            }

            //检查token
            TokenManager tokenService = SpringUtils.getBean(TokenManager.class);
            LoginUserDTO loginUser = tokenService.getLoginUser(request);
            if (loginUser == null) {
                return false;
            }

            //检查账号是否停用
            if (Objects.equals(UserAccountStatusEnum.DISABLE.getCode(), loginUser.getUser().getAccountStatus())) {
                throw new SysException(ExceptionEnum.ACCOUNT_HAS_STOP);
            }

            tokenService.verifyToken(loginUser);
            //检查权限
            PermissionCheck permissionCheck = method.getAnnotation(PermissionCheck.class);
            if (permissionCheck != null) {
                permissionManager.checkUserPermission(loginUser.getUser().getUserId(), permissionCheck.value());
            }
            return true;

        }

        return true;
    }
}
